package com.sghd.candy.module.box.manager;

import com.fasterxml.jackson.core.type.TypeReference;
import com.sghd.pojo.candy.box.enums.OpenType;
import com.sghd.pojo.candy.box.enums.ScopeType;
import com.sghd.common.ramcache.IEntity;
import com.sghd.common.ramcache.PerPersist;
import com.sghd.common.ramcache.anno.*;
import com.sghd.common.ramcache.enhance.Enhance;
import com.sghd.common.utils.json.JsonUtils;
import org.hibernate.annotations.Type;

import javax.management.OperationsException;
import javax.persistence.*;
import java.util.*;

/**
 * @author Allen
 * @date 2018/12/17
 */
@Entity
@Table(catalog = "bsdld")
@Cached(size = CachedSizes.DEFAULT, persister = @Persister(Persisters.PRE_HOUR))
@InitialConfig(type = InitialType.ALL)
public class BoxKeysConfig implements IEntity<Integer>, PerPersist {
    @Id
    private Integer keyId;

    @Column(length = 10)
    private String keyName;

    /** 掉率 */
    private Float dropRate;

    /** 范围 */
    @Transient
    private Set<ScopeType> scopeType;
    @Column(length = 20)
    private String scopeTypeJson;

    /** 是否生效 */
    private Integer isValid;

    @Transient
    private List<BoxOpenDrop> boxOpenDrop;
    private String boxOpenDropJson;

    public Integer getKeyId() {
        return keyId;
    }

    void setKeyId(Integer keyId) {
        this.keyId = keyId;
    }

    public String getKeyName() {
        return keyName;
    }

    void setKeyName(String keyName) {
        this.keyName = keyName;
    }

    public Float getDropRate() {
        return dropRate;
    }

    void setDropRate(Float dropRate) {
        this.dropRate = dropRate;
    }

    public Set<ScopeType> getScopeType() {
        return new HashSet<>(this.scopeType);
    }

    void setScopeType(Set<ScopeType> scopeType) {
        this.scopeType = scopeType;
    }

    public String getScopeTypeJson() {
        return scopeTypeJson;
    }

    public void setScopeTypeJson(String scopeTypeJson) {
        this.scopeTypeJson = scopeTypeJson;
    }

    public Integer getIsValid() {
        return isValid;
    }

    void setIsValid(Integer isValid) {
        this.isValid = isValid;
    }

    public String getBoxOpenDropJson() {
        return boxOpenDropJson;
    }

    public void setBoxOpenDropJson(String boxOpenDropJson) {
        this.boxOpenDropJson = boxOpenDropJson;
    }

    public List<BoxOpenDrop> getBoxOpenDrop() {
        return new ArrayList<>(this.boxOpenDrop);
    }

    void setBoxOpenDrop(List<BoxOpenDrop> boxOpenDrop) {
        this.boxOpenDrop = boxOpenDrop;
    }

    public static BoxKeysConfig valueOf(int keyId, String keyName, float dropRate) {
        BoxKeysConfig boxKeysConfig = new BoxKeysConfig();
        boxKeysConfig.setKeyId(keyId);
        boxKeysConfig.setKeyName(keyName);
        boxKeysConfig.setDropRate(dropRate);
        boxKeysConfig.setBoxOpenDrop(new ArrayList<>());
        boxKeysConfig.setScopeType(new HashSet<>());
        return boxKeysConfig;
    }

    @Enhance
    void config(float dropRate) {
        this.dropRate = dropRate;
    }

    @Enhance
    void config(ScopeType scopeType) {
        this.scopeType.add(scopeType);
    }

    @Enhance
    void config(int isValid) {
        this.isValid = isValid;
    }

    @Enhance
    void config(List<BoxOpenDrop> boxOpenDrop) {
        this.boxOpenDrop.clear();
        this.boxOpenDrop.addAll(boxOpenDrop);
    }
    @Override
    public Integer getId() {
        return this.keyId;
    }

    @Override
    public void afterLoad() {
        this.scopeType = JsonUtils.string2Collection(this.scopeTypeJson, Set.class, ScopeType.class);
        this.boxOpenDrop = new ArrayList<>();
        List<LinkedHashMap> list = JsonUtils.string2Object(this.boxOpenDropJson, List.class);
        for (LinkedHashMap linkedHashMap : list) {
            OpenType openType = OpenType.valueOf((String) linkedHashMap.get("openType"));
            if (openType == OpenType.MONEY) {
                BoxOpenMoney boxOpenMoney = JsonUtils.map2Object(linkedHashMap, new TypeReference<BoxOpenMoney>() {});
                this.boxOpenDrop.add(boxOpenMoney);
            } else if (openType == OpenType.ELEMENT) {
                BoxOpenElement boxOpenElement = JsonUtils.map2Object(linkedHashMap, new TypeReference<BoxOpenElement>() {});
                this.boxOpenDrop.add(boxOpenElement);
            }else if (openType == OpenType.SKILL) {
                BoxOpenSkill boxOpenSkill = JsonUtils.map2Object(linkedHashMap, new TypeReference<BoxOpenSkill>() {});
                this.boxOpenDrop.add(boxOpenSkill);
            }
        }
    }

    @Override
    public void beforePersist() {
        this.scopeTypeJson = JsonUtils.object2String(this.scopeType);
        this.boxOpenDropJson = JsonUtils.object2String(this.boxOpenDrop);
    }
}
